home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / GLOB.C < prev    next >
C/C++ Source or Header  |  1997-08-18  |  5KB  |  219 lines

  1. #ifdef UNIX
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <sys/stat.h>
  5. #include "dirutil.h"
  6.  
  7. #if !defined(_lint)
  8. static char rcsid[] OPTIONAL = "$Id: glob.c,v 1.10 1997/08/19 01:19:22 root Exp root $";
  9. #endif
  10.  
  11.  
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. extern uid_t geteuid (void);
  16. extern gid_t getegid (void);
  17. #ifdef __cplusplus
  18. }
  19. #endif
  20.  
  21. /*
  22.  * Second approximation of glob routine for JNOS/Linux
  23.  */
  24.  
  25. static int ff1(const char *, const char *, const char *, struct ffblk *, int);
  26.  
  27. static char *
  28. __ff_cat(const char *pfx, const char *sfx)
  29. {
  30.     static char buf[1024];
  31.  
  32.     buf[0] = '\0';
  33.     if (pfx && *pfx)
  34.     strcat(buf, pfx);
  35.     if (pfx && *pfx && sfx && *sfx && (*pfx != '/' || pfx[1] != '\0'))
  36.     strcat(buf, "/");
  37.     if (sfx && *sfx)
  38.     strcat(buf, sfx);
  39.     return buf;
  40. }
  41.  
  42. int
  43. findnext(struct ffblk *ff)
  44. {
  45.     struct stat sb;
  46.     char *path;
  47.     int m;
  48.  
  49.     /* special-case literal: if there's no pattern, just close the ff */
  50.     if (!ff->ff_pat || !ff->ff_dir)
  51.     return -1;
  52.     for (;;)
  53.     {
  54.     while ((ff->ff_cur = readdir(ff->ff_dir)) != 0 &&
  55.         wildmat(ff->ff_cur->d_name, ff->ff_pat, 0) == 0)
  56.         ;
  57.     if (!ff->ff_cur)
  58.     {
  59.         (void) closedir(ff->ff_dir);
  60.         ff->ff_dir = 0;
  61.         j_free(ff->ff_pat);
  62.         j_free(ff->ff_pfx);
  63.         return -1;
  64.     }
  65.     path = strdup(__ff_cat(ff->ff_pfx, ff->ff_cur->d_name));
  66.     if ((*ff->ff_cur->d_name == '.' && !(ff->ff_sattr & FA_HIDDEN)) ||
  67.         stat(path, &sb) == -1 ||
  68.         (!(ff->ff_sattr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
  69.         (!S_ISREG(sb.st_mode) && !(ff->ff_sattr & FA_SYSTEM) &&
  70.          !(ff->ff_sattr & FA_HIDDEN)))
  71.     {
  72.         j_free(path);
  73.         continue;
  74.     }
  75.     j_free(path);
  76.     if (geteuid() == sb.st_uid)
  77.         m = 0700;
  78.     else if (getegid() == sb.st_gid)
  79.         m = 0070;
  80.     else
  81.         m = 0007;
  82.     if (!(sb.st_mode & m) && !(ff->ff_sattr & FA_SYSTEM))
  83.         continue;
  84.     ff->ff_ftime = *localtime(&sb.st_mtime);
  85.     ff->ff_fsize = sb.st_size;
  86.     if (S_ISDIR(sb.st_mode))
  87.         ff->ff_attrib = FA_DIREC;
  88.     else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
  89.         ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
  90.     else
  91.         ff->ff_attrib = FA_NORMAL;
  92.     if (*ff->ff_cur->d_name == '.')
  93.         ff->ff_attrib |= FA_HIDDEN;
  94.     if (!(sb.st_mode & m & 0222))
  95.         ff->ff_attrib |= FA_RDONLY;
  96.     strncpy(ff->ff_name, ff->ff_cur->d_name, sizeof(ff->ff_name));
  97.     return 0;
  98.     }
  99. }
  100.  
  101. static int
  102. ff1(const char *prefix, const char *thedir, const char *pat, struct ffblk *ff, int attr)
  103. {
  104.     char *pp, *cp, *ep, *xp;
  105.     char const *bp;
  106.     struct stat sb;
  107.     int m;
  108.  
  109.     ff->ff_pfx = strdup(__ff_cat(prefix, thedir));
  110.     ff->ff_pat = 0;
  111.     ff->ff_dir = 0;
  112.     ff->ff_cur = 0;
  113.     ff->ff_name[0] = '\0';
  114.     ff->ff_sattr = attr;
  115.     cp = ep = pp = strdup(pat);
  116.     xp = 0;
  117.     bp = "";
  118.     for (; *cp; cp = ep)
  119.     {
  120.     while (*ep && *ep != '/') /* extract next component */
  121.     {
  122.         if (*ep == '?' || *ep == '*' || *ep == '[')
  123.         xp = ep;    /* record presence of wildcard characters */
  124.         ep++;
  125.     }
  126.     if (*ep)
  127.         *ep++ = '\0';
  128.     if (xp)            /* if we got a wildcard, abort */
  129.         break;
  130.     if (!*cp || strcmp(cp, ".") == 0) /* prune null components */
  131.         continue;
  132.     xp = ff->ff_pfx;    /* append component to prefix */
  133.     ff->ff_pfx = strdup(__ff_cat(xp, cp));
  134.     j_free(xp);
  135.     xp = 0;
  136.     bp = cp;
  137.     }
  138.     if (!xp)            /* no wildcards; just return it */
  139.     {
  140.     strncpy(ff->ff_name, bp, sizeof(ff->ff_name));
  141.     if ((*bp == '.' && !(attr & FA_HIDDEN)) ||
  142.         stat(ff->ff_pfx, &sb) == -1 ||
  143.         (!(attr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
  144.         (!S_ISREG(sb.st_mode) && !(attr & FA_SYSTEM) &&
  145.          !(attr & FA_HIDDEN)))
  146.     {
  147.         j_free(pp);
  148.         j_free(ff->ff_pfx);
  149.         return -1;
  150.     }
  151.     /* unreadable files are system files */
  152.     /* don't check for root:  if you run nos as root you're dead anyway */
  153.     if (geteuid() == sb.st_uid)
  154.         m = 0700;
  155.     else if (getegid() == sb.st_gid) /* WARNING: ignores group vec */
  156.         m = 0070;
  157.     else
  158.         m = 0007;
  159.     if (!(attr & FA_SYSTEM) && !(sb.st_mode & m))
  160.     {
  161.         j_free(ff->ff_pfx);
  162.         j_free(pp);
  163.         return -1;
  164.     }
  165.     ff->ff_ftime = *localtime(&sb.st_mtime);
  166.     ff->ff_fsize = sb.st_size;
  167.     if (S_ISDIR(sb.st_mode))
  168.         ff->ff_attrib = FA_DIREC;
  169.     else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
  170.         ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
  171.     else
  172.         ff->ff_attrib = FA_NORMAL;
  173.     if (*bp == '.')
  174.         ff->ff_attrib |= FA_HIDDEN;
  175.     if (!(sb.st_mode & m & 0222))
  176.         ff->ff_attrib |= FA_RDONLY;
  177.     j_free(pp);
  178.     j_free(ff->ff_pfx);
  179.     ff->ff_pfx = 0;
  180.     return 0;
  181.     }
  182.     if (*ep)            /* no subdirs this version */
  183.     {
  184.     j_free(ff->ff_pfx);
  185.     j_free(pp);
  186.     return -1;
  187.     }
  188.     ff->ff_pat = strdup(cp);    /* the wildcarded component */
  189.     j_free(pp);
  190.     if ((ff->ff_dir = opendir(*ff->ff_pfx? ff->ff_pfx: ".")) == (DIR *)0)
  191.     {
  192.     j_free(ff->ff_pat);
  193.     j_free(ff->ff_pfx);
  194.     return -1;
  195.     }
  196.     return findnext(ff);
  197. }
  198.  
  199. int
  200. findfirst(const char *pat, struct ffblk *ff, int attr)
  201. {
  202.     return ff1((*pat == '/'? "/": ""), "", (*pat == '/'? pat + 1: pat),
  203.          ff, attr);
  204. }
  205.  
  206. #if 0
  207. void
  208. findlast(struct ffblk *ff)
  209. {
  210.     if (!ff->ff_dir)
  211.       return;
  212.     (void) closedir(ff->ff_dir);
  213.     j_free(ff->ff_pat);
  214.     j_free(ff->ff_pfx);
  215. }
  216. #endif
  217.  
  218. #endif    /* UNIX */
  219.